package ai.people.netmon.utils;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.List;
import java.util.Map;

/**
 * jsonutils
 *
 * @author yuanqinglong
 * @date 2022/1/20 13:45
 */
public class JSONUtils {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        // 允许pojo中有在json串中不存在的字段
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 允许有注释
        OBJECT_MAPPER.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
        OBJECT_MAPPER.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
    }

    /**
     * 解析对象
     *
     * @param inputStream 输入流
     * @param tClass      t类
     * @return {@link T}
     */
    public static <T> T parseObject(InputStream inputStream, Class<T> tClass) {
        Reader reader = new InputStreamReader(inputStream);
        try {
            return OBJECT_MAPPER.readValue(reader, tClass);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 解析对象
     *
     * @param json   json
     * @param tClass t类
     * @return {@link T}
     */
    public static <T> T jsonToBean(String json, Class<T> tClass) {
        try {
            return OBJECT_MAPPER.readValue(json, tClass);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * json字符串
     *
     * @param object 对象
     * @return {@link String}
     */
    public static String beanToJson(Object object) {
        try {
            return OBJECT_MAPPER.writeValueAsString(object);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 映射到bean
     *
     * @param map map
     * @return {@link String}
     */
    public static  <T> T mapToBean(Map<?, ?> map, Class<T> clazz) {
        return jsonToBean(beanToJson(map), clazz);
    }

    /**
     * 解析列表
     *
     * @param json   json
     * @param tClass t类
     * @return {@link List}<{@link T}>
     */
    public static <T> List<T> jsonToList(String json, Class<T> tClass) {
        JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(List.class, tClass);
        try {
            return OBJECT_MAPPER.readValue(json, javaType);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @param outClass 外层对象
     * @param inClass  泛型
     */
    public static <T> T parseObject(String json, Class<T> outClass, Class<?> inClass) {
        JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(outClass, inClass);
        try {
            return OBJECT_MAPPER.readValue(json, javaType);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @param object   外层对象
     * @param outClass 泛型
     */
    public static <T> T convertObject(Object object, Class<T> outClass) {
        return jsonToBean(beanToJson(object), outClass);
    }


}
